(function(weekSelector) {

    //defineWeekSelector
    if (typeof module !== 'undefined' && typeof exports === 'object' && define.cmd) {
        module.exports = weekSelector;
    } else if (typeof define === 'function' && define.amd) {
        define(function() {
            return weekSelector;
        });
    } else {
        window.WeekSelector = weekSelector;
    }

})((function($) {

    var weekSelector = function(opt) {

        this.params = {
            uuid: getUuid(),
            container: '', //容器
            weekTotal: 30, //周次总数
            weekNum: null,
            weekName: null
        };

        //临时变量
        this.isMouseDown = false;
        this.startIndex = -1;
        this.endIndex = -1;

        this.init(opt);
    };

    weekSelector.prototype = {

        init: function(opt) {
            copyPropertyVal(opt, this.params);
        },

        render: function() {
            var html = '<div id="div_' + this.params.uuid + '" class="wt_container">';
            html += '       <span class="wt_span_unedit" id="wt_des_' + this.params.uuid + '"></span>';
            html += '       <div style="margin-bottom:8px;text-align:right">';
            html += '           <input type="button" class="bh-btn bh-btn-primary bh-btn-small-wt" role="selectAll" value="全选" />';
            html += '           <input type="button" class="bh-btn bh-btn-primary bh-btn-small-wt" role="unSelectAll" value="全不选" />';
            html += '           <input type="button" class="bh-btn bh-btn-primary bh-btn-small-wt" role="singleWeek" value="单周" />';
            html += '           <input type="button" class="bh-btn bh-btn-primary bh-btn-small-wt" role="doubleWeek" value="双周" />';
            html += '       </div>';
            html += '       <table class="wt_table" onselectstart="return false">';
            html += '           <tr>';
            for (var i = 1; i <= this.params.weekTotal; i++) {
                if (i % 2 === 0) {
                    continue;
                }
                html += '           <td role="item" role-selected="0" role-index="' + i + '">' + i + '</td>';
            }
            html += '           </tr>';
            html += '           <tr>';
            for (var i = 1; i <= this.params.weekTotal; i++) {
                if (i % 2 !== 0) {
                    continue;
                }
                html += '           <td role="item" role-selected="0" role-index="' + i + '">' + i + '</td>';
            }
            html += '           </tr>';
            html += '       </table>';
            html += '   </div>';

            $(this.params.container).html(html);

            this.settingDefaultValue();
            this.bindEvent();
        },

        /**
         * 设置默认值
         */
        settingDefaultValue: function() {
            if (this.params.weekNum != null) {
                var indexs = getWeekIndexs(this.params.weekNum);
                for (var i = 0; i < indexs.length; i++) {
                    $('#div_' + this.params.uuid).find('td[role-index="' + indexs[i] + '"]').addClass("wt_selected").attr("role-selected", "1");
                }
            }
            
            if (this.params.weekName == null) {
                this.params.weekName = this.buildWeekName(this.params.weekNum || '');
            }
            $('#wt_des_' + this.params.uuid).html(this.params.weekName).attr("title", this.params.weekName);
        },

        bindEvent: function() {
            var _this = this;

            // 给周次元素绑定事件
            $('#div_' + this.params.uuid).find('td[role="item"]').mousedown(function(e) {
                var jdom = $(this);
                jdom.addClass("wt_selecting");

                _this.isMouseDown = true;
                _this.startIndex = parseInt(jdom.attr("role-index"));

            }).mousemove(function(e) {
                if (!_this.isMouseDown) {
                    return;
                }

                var jdom = $(this);
                var _index = parseInt(jdom.attr("role-index"));
                if (_index === _this.endIndex) {
                    return;
                }

                _this.clearAllSelectingClass();
                _this.endIndex = parseInt(jdom.attr("role-index"));

                // 获取开始下标和结束下标
                var startIndex = _this.startIndex < _this.endIndex ? _this.startIndex : _this.endIndex;
                var endIndex = _this.startIndex > _this.endIndex ? _this.startIndex : _this.endIndex;

                // 如果开始下标和结束下标都是偶数
                if (startIndex % 2 === 0 && endIndex % 2 === 0) {
                    for (var i = startIndex; i <= endIndex; i++) {
                        if (i % 2 === 0) {
                            $('#div_' + _this.params.uuid).find('td[role-index="' + i + '"]').addClass("wt_selecting");
                        }
                    }
                } else if (startIndex % 2 !== 0 && endIndex % 2 !== 0) {
                    // 如果开始下标和结束下标都是奇数
                    for (var i = startIndex; i <= endIndex; i++) {
                        if (i % 2 !== 0) {
                            $('#div_' + _this.params.uuid).find('td[role-index="' + i + '"]').addClass("wt_selecting");
                        }
                    }
                } else if (startIndex % 2 !== 0 && endIndex % 2 === 0) {
                    // 如果开始下标为奇数，结束下标为偶数
                    for (var i = startIndex; i <= endIndex; i++) {
                        $('#div_' + _this.params.uuid).find('td[role-index="' + i + '"]').addClass("wt_selecting");
                    }
                } else if (startIndex % 2 === 0 && endIndex % 2 !== 0) {
                    // 如果开始下标为偶数，结束下标为奇数
                    for (var i = startIndex - 1; i <= endIndex + 1; i++) {
                        $('#div_' + _this.params.uuid).find('td[role-index="' + i + '"]').addClass("wt_selecting");
                    }
                }

            }).mouseup(function(e) {
                _this.isMouseDown = false;
                _this.doSelected();
            });

            // 绑定按钮点击事件
            // 全选
            $('#div_' + this.params.uuid).find('input[role="selectAll"]').click(function() {
                var weekNum = '';
                for (var i = 1; i <= _this.params.weekTotal; i++) {
                    weekNum += '1';
                }
                _this.doCustomSelected(weekNum);
            });

            // 全不选
            $('#div_' + this.params.uuid).find('input[role="unSelectAll"]').click(function() {
                var weekNum = '';
                for (var i = 1; i <= _this.params.weekTotal; i++) {
                    weekNum += '0';
                }
                _this.doCustomSelected(weekNum);
            });

            // 单周
            $('#div_' + this.params.uuid).find('input[role="singleWeek"]').click(function() {
                var weekNum = '';
                for (var i = 1; i <= _this.params.weekTotal; i++) {
                    weekNum += (i % 2 !== 0) ? '1' : '0';
                }
                _this.doCustomSelected(weekNum);
            });

            // 双周
            $('#div_' + this.params.uuid).find('input[role="doubleWeek"]').click(function() {
                var weekNum = '';
                for (var i = 1; i <= _this.params.weekTotal; i++) {
                    weekNum += (i % 2 === 0) ? '1' : '0';
                }
                _this.doCustomSelected(weekNum);
            });
        },

        /**
         * 处理选择
         */
        doSelected: function() {
            this.buildResult();
            this.renderResult();
            this.clearAllSelectingClass();
        },

        /**
         * 自定义选择
         */
        doCustomSelected: function(weekNum) {
            $('#div_' + this.params.uuid).find('td[role="item"]').removeClass("wt_selected").removeClass("wt_selecting").attr("role-selected", "0");

            var indexs = getWeekIndexs(weekNum);
            for (var i = 0; i < indexs.length; i++) {
                $('#div_' + this.params.uuid).find('td[role-index="' + indexs[i] + '"]').attr("role-selected", "1").addClass("wt_selected");
            }

            this.buildResult(weekNum);
            this.renderResult();
            this.clearAllSelectingClass();
        },

        getResult: function() {
            return {
                weekNum: this.params.weekNum,
                weekName: this.params.weekName
            };
        },

        /**
         * 清除所有当前正在选择的样式
         */
        clearAllSelectingClass: function() {
            $('#div_' + this.params.uuid).find('td[role="item"]').removeClass("wt_selecting");
        },

        /**
         * 渲染结果
         */
        renderResult: function() {
            $('#wt_des_' + this.params.uuid).html(this.params.weekName).attr("title", this.params.weekName);;
        },

        /**
         * 构建返回结果
         */
        buildResult: function(params_weekNum) {
            this.params.weekNum = params_weekNum != null ? params_weekNum : this.buildWeekNum();
            this.params.weekName = this.buildWeekName(this.params.weekNum);
        },

        /**
         * 构建周次串(00010101000)
         */
        buildWeekNum: function() {
            var _this = this;
            var choiced = []; // 选中的数

            // 先去除所有选中的元素的样式
            $('#div_' + this.params.uuid).find('td[role="item"]').removeClass("wt_selected");

            // 根据当前选的元素，来判断哪些元素被选中，同时将状态保存在dom属性中
            $('#div_' + this.params.uuid).find(".wt_selecting").each(function() {
                var jdom = $(this);
                var index = parseInt(jdom.attr("role-index"));
                var selected = jdom.attr("role-selected");
                if (selected === "1") {
                    jdom.attr("role-selected", "0");
                } else {
                    jdom.attr("role-selected", "1");
                }
            });

            // 根据dom属性来确定所有选中的元素，并赋值样式
            $('#div_' + this.params.uuid).find('td[role="item"]').each(function() {
                var jdom = $(this);
                var index = parseInt(jdom.attr("role-index"));
                var selected = jdom.attr("role-selected");
                if (selected === "1") {
                    choiced.push(index);
                    jdom.addClass("wt_selected");
                }
            });

            var weekNum = '';
            for (var i = 1; i <= this.params.weekTotal; i++) {
                weekNum += contains(choiced, i) ? "1" : "0";
            }
            return weekNum;
        },

        /**
         * 构建周次名称(13-21单周)
         */
        buildWeekName: function(weeks) {
            var weeksString = '';
            if (typeof weeks === 'undefined') {
                return weeksString;
            }

            var f = true;
            var tempArr = [];
            var weeksArr = weeks.split('');
            for (var i = 0; i < weeksArr.length; i++) {
                var w = Number(weeksArr[i]);
                if (w === 1) {
                    tempArr.push(Number(i + 1));
                }
            }
            if (tempArr.length === 0) {
                return '';
            }
            if (tempArr.length === 1) {
                f = false;
            } else {
                for (var i = tempArr.length - 1; i >= 0; i--) {
                    if (i > 0) {
                        if (Number(tempArr[i]) != Number(tempArr[i - 1]) + 2) {
                            f = false;
                            break;
                        }
                    }
                }
                for (var i = tempArr.length - 1; i >= 0; i--) {
                    if (i > 0) {
                        if ((Number(tempArr[i]) - 1) === Number(tempArr[i - 1])) {
                            tempArr.splice(i, 1, '-' + tempArr[i]);
                            f = false;
                        }
                    }
                }
            }
            if (f) {
                var even = 0;
                var odd = 0;
                for (var i = 0; i < tempArr.length; i++) {
                    var w = Number(tempArr[i]);
                    if (w % 2 === 0) {
                        even++;
                    } else {
                        odd++;
                    }
                }
                if (odd === 0 && even === tempArr.length) {
                    for (var i = tempArr.length - 2; i > 0; i--) {
                        tempArr.splice(i, 1);
                    }
                    weeksString = tempArr.join('-') + '双周';
                } else if (even === 0 && odd === tempArr.length) {
                    for (var i = tempArr.length - 2; i > 0; i--) {
                        tempArr.splice(i, 1);
                    }
                    weeksString = tempArr.join('-') + '单周';
                } else {
                    weeksString = tempArr.join(',');
                }
            } else {
                for (var i = 0; i < tempArr.length; i++) {
                    var w = Number(tempArr[i]);
                    if (w < 0) {
                        if (tempArr[i + 1] != null && Number(tempArr[i + 1] < 0)) {
                            delete tempArr[i];
                        }
                    }
                }
                for (var i = tempArr.length - 1; i >= 0; i--) {
                    var w = tempArr[i];
                    if (w == null) {
                        tempArr.splice(i, 1);
                    }
                }
                weeksString = tempArr.join(',').replace(new RegExp(',-', 'gm'), '-');
            }

            function startWith(str1, str2) {
                var reg = new RegExp("^" + str2);
                return reg.test(str1);
            }

            function replaceStr(weeks) {
                var arr = weeks.split(',');
                var t = 0;
                for (var i = arr.length - 1; i >= 0; i--) {
                    var week = arr[i];
                    if (week.indexOf('-') === -1) {
                        if (i > 0) {
                            if ((Number(week) - 2) === Number(arr[i - 1])) {
                                arr.splice(i, 1, '-' + arr[i] + ((Number(week) % 2 === 0) ? '双周' : '单周'));
                            }
                        }
                    }
                }
                for (var i = arr.length - 1; i >= 0; i--) {
                    var w = arr[i];
                    if (startWith(w, '-') === true && startWith(arr[i - 1], '-') === true && (w.substr(w.length - 2) === arr[i - 1].substr(arr[i - 1].length - 2))) {
                        arr.splice(i - 1, 1);
                    }
                }
                return arr.join(',').replace(new RegExp(',-', 'gm'), '-');
            }
            weeksString = replaceStr(weeksString);
            return weeksString;
        }
    };

    /**
     * 获取已选择的周次的下标，下标从1开始
     * @param binaryStr 二进制串
     */
    function getWeekIndexs(binaryStr) {
        var indexArrs = [];
        for (i = 0; i < binaryStr.length; i++) {
            var bs = binaryStr.charAt(i);
            if (bs === "1") {
                indexArrs.push(i + 1);
            }
        }
        return indexArrs;
    }

    /**
     * 数组是否包含
     * @param arrs
     * @param val
     */
    function contains(arrs, val) {
        for (var i = 0; i < arrs.length; i++) {
            if (arrs[i] === val) {
                return true;
            }
        }
        return false;
    }

    /**
     * 参数复制
     * @param from
     * @param to
     */
    function copyPropertyVal(from, to) {
        for (var f in from) {
            for (var t in to) {
                if (f === t && typeof from[f] !== 'undefined') {
                    to[t] = from[f];
                    break;
                }
            }
        }
    }

    /**
     * 获取uuid
     * @returns {string}
     */
    function getUuid() {
        var s = [];
        var hexDigits = "0123456789abcdef";
        for (var i = 0; i < 36; i++) {
            s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
        }
        s[14] = "4";
        s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
        //s[8] = s[13] = s[18] = s[23] = "-";
        s[8] = s[13] = s[18] = s[23] = "";

        var uuid = s.join("");
        return uuid;
    }

    return weekSelector;

}(jQuery)));
